package yanc.app;

import org.apache.commons.codec.binary.Base64;

import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * @Author: huoo
 * @version: 1.0.0
 * @Description:
 * @Date: create in 15:48 2017/10/23
 * @Modified By:
 */
public class SignUtils {
    public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
    public static final String ENCODE_ALGORITHM = "SHA-256";
    public static final String PLAIN_TEXT = "13456780098123213registry";

    public static void main(String[] args) {
        // 公私钥对
//        Map<String, byte[]> keyMap = RSA.generateKeyBytes();
//        PublicKey publicKey = RSA.restorePublicKey(keyMap.get(RSA.PUBLIC_KEY));
//        PrivateKey privateKey = RSA.restorePrivateKey(keyMap.get(RSA.PRIVATE_KEY));
//
//
//        Map<String,Object> keys = new HashMap<>();
//        keys.put(RSA.PUBLIC_KEY,publicKey);
//        keys.put(RSA.PRIVATE_KEY,privateKey);
        String priKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCJu/ox1nAsPC6r0VMO9QtIBEKYjbXvYfczk2AY6Nyb1gpUEDxrF5F6G5WO47flQmB7FERXy0mUc1w/pcgZIxijcBz0F1NGthcSsFKWfDPF0WtAQVGBUtHr8+tvN7/Uhte4xst17JxX82uo65xXIOp3WBbW4Jm0h9bKKhufGWS2nxVYV85mD1HiN+IhaijRc87FBHrmkg1v6SG/vN+p1DGf5SjnYyeMHi/+OXy9rvRU6HEtAW6968eHsgLR/B+IwaDcHVbAgb/Gdyn4pAAju+YZ5Co53eXPM61RtwyEj+1Pn3QaGAmlPp8MFKchuS3qD9z5nUfYBScyoyygh5WfhoztAgMBAAECggEAAq1uza03fQSme5yUGsRUtc+vY7vNf5vN7Gi/A3zzXOwqQzwVkJdispb6r05p8sD5kyrvsS04fvRHJM2aODLgdbzmMzCI4+UCSdC3qkk70GqjxRn/9Z2giw+w0fapef4tD2B98ArrdyI6Q4xg+6ieJjfGKeMv2bySRlfPNaaOuKYTnGwvrBRu/XmvjXa/qZyY3rctBbbJpHGGFWZWjkBvpJ96EbvsXRgNYyqzzT3vaWv4xKzDn+3WLqvTt5kd1A65q6PbHuZKYFv/+Rg32tbwgAEaC0KZBw+HoTEyMdYAV9GhEdgRJW5rDiSx7+iCw9GnbxTZBg6Y23p9Aw8E+E0g2QKBgQDiYeUKy0Wmny5KnmbGMoot2UwmckUdwhFYAk6iLdwBErU13Xbq9MwJJcFrI//eWdsGd21OY3PUjLdvQV5lZHcR9gckGGMyyytZatkhK0rYYahvMX+7ujPDjGa9o1a6DPDE17aeQaeqR+XdJLC5l0MH6Wkb63l0iuVksrRG2qUx/wKBgQCbwQnadWQt5HV99ksYmgmuuRLOcrsuhwcavCPmjw+FIt1skPUO+UwG2g77ggaQrzhhVgYzgShakHpMJSVG95Il7wX4O1O+r0O1z0LX7Qd9p9YLVjRPhp7ropX1DWQqdIWDj1BXZUjklAHDCP/hKu3v13tIrYaxCFMu5vyyK74pEwKBgQC2VIJVH0MJ4Es4bjv4hdwk8U8T6BUi0puFdtY+aRE5DAhHSgftVRzAgVg3IteCDn0JyEaRTCiOmIdlZBDTOQdtv+ogeEPtNRXE/vnCbUvq2zz90bA/Usk+Rma5dkTztFh3MgYzkE2qKB5K7rInyFyEksnFYvJ/mx8G66enKZLDoQKBgCq1pXENLbpT4k/3IKKPYsZRo7GOzns0taMEIkgPxK66X8NsgHZpsApU8zTOc+Rq1+gBAdRPv3QOGCsXKICsVJwoThfClPU99DA/tFGngp1XT59uNQv1m1B8FejLkkL+DrqDqwE8Gd/sIguMRTZGYlaZXQoR41RaNw0uc+6bhhqXAoGAXXBFaHT7MCL//4w15UunRXyAhB7tzC/4qt9R9tdcifQ3IYMuWTGp+fYczBAbqS0UKeq3WetnFk+vgg38ld+oteQv23qnWMKKsDuhH4NNBTTwXCoPlvV/0dtntRXFXJEJcYHZUtyoMnIjzINWLE6rh4bhxuCiVt1I0AnA7FoVnUo=";
        String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAibv6MdZwLDwuq9FTDvULSARCmI2172H3M5NgGOjcm9YKVBA8axeRehuVjuO35UJgexREV8tJlHNcP6XIGSMYo3Ac9BdTRrYXErBSlnwzxdFrQEFRgVLR6/Prbze/1IbXuMbLdeycV/NrqOucVyDqd1gW1uCZtIfWyiobnxlktp8VWFfOZg9R4jfiIWoo0XPOxQR65pINb+khv7zfqdQxn+Uo52MnjB4v/jl8va70VOhxLQFuvevHh7IC0fwfiMGg3B1WwIG/xncp+KQAI7vmGeQqOd3lzzOtUbcMhI/tT590GhgJpT6fDBSnIbkt6g/c+Z1H2AUnMqMsoIeVn4aM7QIDAQAB";
        /*try {
            priKey = RSA.getPrivateKey(keys);
            pubKey = RSA.getPublicKey(keys);
        } catch (Exception e) {
            e.printStackTrace();
        }*/

        /*System.out.println("私钥=" + priKey);
        System.out.println("公钥=" + pubKey);*/

        // 签名
        byte[] sing_byte = sign(priKey, PLAIN_TEXT);
        String signInfo = Base64.encodeBase64String(sing_byte);
        System.out.println(signInfo);
        // 验签
        verifySign(pubKey, PLAIN_TEXT, signInfo);
    }

    /**
     * 签名
     *
     * @param privateKey
     *            私钥
     * @param plain_text
     *            明文
     * @return
     */
    public static byte[] sign(String privateKey, String plain_text) {


        MessageDigest messageDigest;
        byte[] signed = null;
        try {
            byte[] pribyte = Base64.decodeBase64(privateKey);
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(pribyte);
            KeyFactory keyFactory = KeyFactory.getInstance(RSA.KEY_ALGORITHM);
            PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
            Signature Sign = Signature.getInstance(SIGNATURE_ALGORITHM);
            Sign.initSign(privateK);
            Sign.update(plain_text.getBytes("utf-8"));
            signed = Sign.sign();
        } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return signed;
    }

    /**
     * 验签 签名之后的byte[]
     *
     * @param publicKey
     *            公钥
     * @param plain_text
     *            明文
     * @param signed
     *            签名
     */
    public static boolean verifySign(String publicKey, String plain_text, String signed) {

        byte[]  signedByte = Base64.decodeBase64(signed);
        MessageDigest messageDigest;
        boolean SignedSuccess=false;
        try {
            byte[] pubKey = Base64.decodeBase64(publicKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubKey);
            KeyFactory keyFactory = KeyFactory.getInstance(RSA.KEY_ALGORITHM);
            PublicKey publicK = keyFactory.generatePublic(keySpec);
            Signature verifySign = Signature.getInstance(SIGNATURE_ALGORITHM);
            verifySign.initVerify(publicK);
            verifySign.update(plain_text.getBytes("utf-8"));
            SignedSuccess = verifySign.verify(signedByte);
            System.out.println("验证成功？---" + SignedSuccess);
        } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return SignedSuccess;
    }

    /**
     * bytes[]换成16进制字符串
     *
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }
}
